package com.replication.jdbc.statement;

import com.replication.constants.ReplicationConstants;
import com.replication.jdbc.connection.ReplicationConnectionProxy;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author fire
 * @date 15/10/26.
 */
public class Statements {
    public Statements() {
    }

    public static Statement createStatement(Connection conn, Integer resultSetType, Integer resultSetConcurrency, Integer resultSetHoldability) throws SQLException {
        return resultSetType != null && resultSetConcurrency != null && resultSetHoldability != null?conn.createStatement(resultSetType.intValue(), resultSetConcurrency.intValue(), resultSetHoldability.intValue()):(resultSetType != null && resultSetConcurrency != null?conn.createStatement(resultSetType.intValue(), resultSetConcurrency.intValue()):conn.createStatement());
    }

    public static Statement createStatement(ReplicationConnectionProxy conn, String sql, StatementOpts opts, Integer resultSetType, Integer resultSetConcurrency, Integer resultSetHoldability) throws SQLException {
        Statement result = null;
        result = createStatement(getTargetConnection(conn, sql), resultSetType, resultSetConcurrency, resultSetHoldability);
        opts.bound(result);
        return result;
    }

    public static Statement createStatementOnMaster(ReplicationConnectionProxy conn, StatementOpts opts, Integer resultSetType, Integer resultSetConcurrency, Integer resultSetHoldability) throws SQLException {
        Statement result = createStatement(conn.getMasterConnection(), resultSetType, resultSetConcurrency, resultSetHoldability);
        opts.bound(result);
        return result;
    }

    public static Connection getTargetConnection(ReplicationConnectionProxy conn, String sql) throws SQLException {
        return conn.getConnectionSelector().select(conn, sql);
    }

    public static PreparedStatement prepareStatement(ReplicationConnectionProxy conn, String sql) throws SQLException {
        PreparedStatement result = null;
        result = getTargetConnection(conn, sql).prepareStatement(removeMasterHint(sql));
        return result;
    }

    public static PreparedStatement prepareStatement(ReplicationConnectionProxy conn, String sql, int autoGeneratedKeys) throws SQLException {
        return getTargetConnection(conn, sql).prepareStatement(removeMasterHint(sql), autoGeneratedKeys);
    }

    public static PreparedStatement prepareStatement(ReplicationConnectionProxy conn, String sql, int[] columnIndexes) throws SQLException {
        return getTargetConnection(conn, sql).prepareStatement(removeMasterHint(sql), columnIndexes);
    }

    public static PreparedStatement prepareStatement(ReplicationConnectionProxy conn, String sql, String[] columnNames) throws SQLException {
        return getTargetConnection(conn, sql).prepareStatement(removeMasterHint(sql), columnNames);
    }

    public static PreparedStatement prepareStatement(ReplicationConnectionProxy conn, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return getTargetConnection(conn, sql).prepareStatement(removeMasterHint(sql), resultSetType, resultSetConcurrency);
    }

    public static PreparedStatement prepareStatement(ReplicationConnectionProxy conn, String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return getTargetConnection(conn, sql).prepareStatement(removeMasterHint(sql), resultSetType, resultSetConcurrency, resultSetHoldability);
    }

    public static String removeMasterHint(String sql) {
        if(!sql.startsWith(ReplicationConstants.MASTER_HINT)) {
            return sql;
        }
        return sql.replaceFirst(ReplicationConstants.MASTER_HINT, "");
    }
}
